{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 面向对象"
   ]
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "青海\n",
      "江西\n",
      "给青海的x1发送一个邮件\n",
      "给江西的xx发送一个邮件\n"
     ]
    }
   ],
   "source": [
    "# 类\n",
    "class MessageInfo:\n",
    "\n",
    "    # self=this\n",
    "    def send_email(self, to_email):\n",
    "        msg = \"给{}的{}发送一个邮件\".format(self.name, to_email)\n",
    "        print(msg)\n",
    "\n",
    "    def send_dingding(self, to_email):\n",
    "        msg = \"给{}发送一个钉钉\".format(to_email)\n",
    "        print(msg)\n",
    "\n",
    "\n",
    "# 创建一个MessageInfo类的对象； 实例化了MessageInfo类的对象。\n",
    "obj1 = MessageInfo()\n",
    "obj2 = MessageInfo()\n",
    "\n",
    "obj1.name = \"青海\"\n",
    "print(obj1.name)\n",
    "obj2.name = \"江西\"\n",
    "print(obj2.name)\n",
    "\n",
    "obj1.send_email(\"x1\")\n",
    "obj2.send_email(\"xx\")"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-18T03:50:35.309714100Z",
     "start_time": "2024-01-18T03:50:35.271731500Z"
    }
   },
   "execution_count": 5
  },
  {
   "cell_type": "markdown",
   "source": [
    "![jupyter](./png/img_4.png)"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "给江西的x1发送一个邮件\n",
      "给青海的x2发送一个邮件\n"
     ]
    }
   ],
   "source": [
    "class MessageInfo2:\n",
    "    # 一般在创建对象时执行，可以为空对象中初始化一些值\n",
    "    def __init__(self, city):\n",
    "        self.city = city\n",
    "        self.company = \"联通\"\n",
    "\n",
    "    def send_email(self, to_email):\n",
    "        msg = \"给{}的{}发送一个邮件\".format(self.city, to_email)\n",
    "        print(msg)\n",
    "\n",
    "\n",
    "# 第1步：obj1 = 创建空对象\n",
    "# 第2步：执行初始化  obj1.__init__(obj1, \"江西\")\n",
    "obj1 = MessageInfo2(\"江西\")\n",
    "obj2 = MessageInfo2(\"青海\")\n",
    "obj1.send_email(\"x1\")\n",
    "obj2.send_email(\"x2\")"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-18T03:54:18.988336200Z",
     "start_time": "2024-01-18T03:54:18.946900700Z"
    }
   },
   "execution_count": 10
  },
  {
   "cell_type": "markdown",
   "source": [
    "![jupyter](./png/img_5.png)"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 类的作用\n",
    "封装数据"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "\"\"\"\n",
    "user_list = [\n",
    "\t{\"name\":\"战1\",age:\"19\"},\n",
    "\t{\"name\":\"战2\",age:\"19\"},\n",
    "\t{\"name\":\"战3\",age:\"19\"},\n",
    "]\n",
    "\"\"\"\n",
    "user_list = []\n",
    "\n",
    "while True:\n",
    "    name = input(\"姓名：\")\n",
    "    if name.upper() == \"Q\":\n",
    "        break\n",
    "    age = input(\"年龄：\")\n",
    "\n",
    "    info = {\"name\": name, \"age\": age}\n",
    "    user_list.append(info)\n",
    "\n",
    "for item in user_list:\n",
    "    item['name']\n",
    "    item['age']"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-18T03:58:18.546467300Z",
     "start_time": "2024-01-18T03:58:09.517227200Z"
    }
   },
   "execution_count": 12
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "class UserInfo:\n",
    "    def __init__(self, name, age):\n",
    "        self.name = name\n",
    "        self.age = age\n",
    "\n",
    "    def show(self):\n",
    "        message = \"我的姓名：{}，今年{}岁\".format(self.name, self.age)\n",
    "        print(message)\n",
    "\n",
    "\n",
    "\"\"\"\n",
    "user_list = [\n",
    "\t对象（name=武沛齐,age19),\n",
    "\t对象（name=root,age19),\n",
    "]\n",
    "\"\"\"\n",
    "user_list = []\n",
    "\n",
    "while True:\n",
    "    name = input(\"姓名：\")\n",
    "    if name.upper() == \"Q\":\n",
    "        break\n",
    "    age = input(\"年龄：\")\n",
    "\n",
    "    info = UserInfo(name, age)\n",
    "    user_list.append(info)\n",
    "\n",
    "for item in user_list:\n",
    "    # item.name\n",
    "    # item.age\n",
    "    item.show()"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 封装"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "class Foo:\n",
    "\n",
    "    def __init__(self, name, age):\n",
    "        self.name = name\n",
    "        self.age = age\n",
    "\n",
    "\n",
    "obj1 = Foo(\"武沛齐\", 10)\n",
    "obj2 = Foo(\"联通\", 10)\n",
    "obj3 = Foo(\"青海\", 10)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-18T05:10:50.077283400Z",
     "start_time": "2024-01-18T05:10:50.034945700Z"
    }
   },
   "execution_count": 1
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 继承"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "class Base:\n",
    "    pass\n",
    "\n",
    "\n",
    "class Son(Base):\n",
    "    pass"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "class Base:\n",
    "    def x2(self):\n",
    "        pass\n",
    "\n",
    "\n",
    "class F1(Base):\n",
    "    def x1(self):\n",
    "        pass\n",
    "\n",
    "\n",
    "class F2(Base):\n",
    "    def x3(self):\n",
    "        pass"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "# 多继承时，先去左边找，再去右边找。\n",
    "class F1:\n",
    "    pass\n",
    "\n",
    "\n",
    "class F2:\n",
    "    pass\n",
    "\n",
    "\n",
    "class F3(F1, F2):\n",
    "    pass"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "TCPServer\n"
     ]
    }
   ],
   "source": [
    "class TCPServer:\n",
    "    def f1(self):\n",
    "        print(\"TCPServer\")\n",
    "\n",
    "\n",
    "class ThreadingMixIn:\n",
    "    def f1(self):\n",
    "        print(\"ThreadingMixIn\")\n",
    "\n",
    "\n",
    "class ThreadingTCPServer(TCPServer, ThreadingMixIn):\n",
    "    def run(self):\n",
    "        self.f1()\n",
    "\n",
    "\n",
    "obj = ThreadingTCPServer()\n",
    "obj.run()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-18T05:19:10.449362400Z",
     "start_time": "2024-01-18T05:19:10.402773400Z"
    }
   },
   "execution_count": 4
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "before\n",
      "ThreadingMixIn\n",
      "after\n"
     ]
    }
   ],
   "source": [
    "class TCPServer1:\n",
    "    def f1(self):\n",
    "        print(\"TCPServer\")\n",
    "\n",
    "    def run(self):\n",
    "        print('before')\n",
    "        self.f1()  # # self=obj  -> obj.f1() -> ThreadingTCPServer\n",
    "        print('after')\n",
    "\n",
    "\n",
    "class ThreadingMixIn1:\n",
    "    def f1(self):\n",
    "        print(\"ThreadingMixIn\")\n",
    "\n",
    "\n",
    "class ThreadingTCPServer1(ThreadingMixIn1, TCPServer1):\n",
    "    pass\n",
    "\n",
    "\n",
    "obj = ThreadingTCPServer1()\n",
    "obj.run()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-18T05:21:55.643885Z",
     "start_time": "2024-01-18T05:21:55.602276800Z"
    }
   },
   "execution_count": 7
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 多态\n",
    "python默认支持多态"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "def func(data):\n",
    "    print(data)\n",
    "\n",
    "\n",
    "func(11)\n",
    "func(\"xxx\")\n",
    "func([11, 22, 33, 44])"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "# 鸭子模型\n",
    "def func(data):\n",
    "    data.upper()\n",
    "\n",
    "\n",
    "func(11)\n",
    "func([11, 22, 3])\n",
    "\n",
    "# 1. 可以传递任意类型，传什么都能接受。 【鸭子、八哥、狗子、狼】\n",
    "# 2. data.upper方法，传入的参数有upper方法，如果没有程序报错了。【呱呱叫，你是鸭子】"
   ],
   "metadata": {
    "collapsed": false
   },
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "source": [],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 成员\n",
    "实例变量/字段\n",
    "类变量/静态变量"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "上海\n",
      "青海\n",
      "上海\n"
     ]
    }
   ],
   "source": [
    "class Info:\n",
    "    # 静态变量/类变量\n",
    "    city = \"上海\"\n",
    "\n",
    "    def __init__(self, name):\n",
    "        # 字段/实例变量\n",
    "        self.name = name\n",
    "\n",
    "    # 方法\n",
    "    def send(self):\n",
    "        pass\n",
    "\n",
    "\n",
    "print(Info.city)\n",
    "v1 = Info(\"青海\")\n",
    "print(v1.name)\n",
    "print(v1.city)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-18T05:25:56.204185100Z",
     "start_time": "2024-01-18T05:25:56.161224300Z"
    }
   },
   "execution_count": 9
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 方法"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "class Info:\n",
    "\n",
    "    # 方法=绑定方法:至少有一个self参数\n",
    "    def send(self):\n",
    "        pass\n",
    "\n",
    "    # 静态方法\n",
    "    @staticmethod\n",
    "    def get_data():\n",
    "        pass\n",
    "\n",
    "    # 类方法  至少有一个cls的参数\n",
    "    @classmethod\n",
    "    def fetch(cls, a1):\n",
    "        pass\n",
    "\n",
    "\n",
    "obj = Info()\n",
    "obj.send()\n",
    "\n",
    "Info.get_data()\n",
    "obj.get_data()\n",
    "\n",
    "Info.fetch(12)\n",
    "obj.fetch(333)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-18T06:26:41.893508800Z",
     "start_time": "2024-01-18T06:26:41.839355Z"
    }
   },
   "execution_count": 11
  },
  {
   "cell_type": "markdown",
   "source": [],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 属性"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "class Foo:\n",
    "    def d1(self):\n",
    "        return 123\n",
    "\n",
    "\n",
    "obj = Foo()\n",
    "v1 = obj.d1()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-18T06:36:48.717362300Z",
     "start_time": "2024-01-18T06:36:48.672715400Z"
    }
   },
   "execution_count": 12
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "123\n"
     ]
    }
   ],
   "source": [
    "\n",
    "class Foo:\n",
    "    @property  # 方法->属性 调用不带()  只能有1个参数\n",
    "    def d1(self):\n",
    "        return 123\n",
    "\n",
    "\n",
    "obj = Foo()\n",
    "print(obj.d1)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-18T06:36:56.570990900Z",
     "start_time": "2024-01-18T06:36:56.512002300Z"
    }
   },
   "execution_count": 13
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "class Foo:\n",
    "    def __init__(self, name, age):\n",
    "        self.name = name\n",
    "        self.age = age\n",
    "\n",
    "        @property\n",
    "        def d1(self):\n",
    "            return \"{}-{}\".format(self.name, self.age)\n",
    "\n",
    "\n",
    "obj = Foo()\n",
    "obj.d1\n",
    "obj.name\n",
    "obj.age"
   ],
   "metadata": {
    "collapsed": false
   },
   "execution_count": null
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "class Foo:\n",
    "    def __init__(self, name, age):\n",
    "        self.name = name\n",
    "        self.age = age\n",
    "\n",
    "        @property\n",
    "        def d1(self):\n",
    "            return \"{}-{}\".format(self.name, self.age)\n",
    "\n",
    "    @d1.setter\n",
    "    def d1(self, value):\n",
    "        self.age = value\n",
    "\n",
    "    @d1.deleter\n",
    "    def d1(self):\n",
    "        pass\n",
    "\n",
    "\n",
    "obj = Foo(\"root\", 10)\n",
    "\n",
    "obj.d1\n",
    "obj.d1 = 123\n",
    "del obj.d1"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "class Foo:\n",
    "    def __init__(self, name, age):\n",
    "        self.name = name\n",
    "        self.age = age\n",
    "\n",
    "        def getx(self):\n",
    "            return 123\n",
    "\n",
    "    def setx(self, value):\n",
    "        pass\n",
    "\n",
    "    def delx(self):\n",
    "        pass\n",
    "\n",
    "    x = property(getx, setx, delx)\n",
    "\n",
    "\n",
    "obj = Foo(\"root\", 10)\n",
    "\n",
    "obj.x\n",
    "obj.x = 999\n",
    "del obj.x"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 特殊成员"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "# __init__，初始化方法\n",
    "class Foo:\n",
    "    def __init__(self, name):\n",
    "        self.name = name\n",
    "\n",
    "\n",
    "obj = Foo(\"xxx\")"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "# `__new__`，构造方法\n",
    "class Foo:\n",
    "    def __init__(self, name):\n",
    "        self.name = name\n",
    "\n",
    "    def __new__(self, *args, **kwargs):\n",
    "        obj = object.__new__(self)\n",
    "        return obj\n",
    "\n",
    "\n",
    "# 1.创建空对象 obj=对象（内容是空）        new，创建对象\n",
    "# 2.执行init方法 obj.__init__(\"xxx\")    init，初始化\n",
    "obj = Foo(\"xxx\")"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "# `__call__`，对象() 执行此方法\n",
    "class Foo:\n",
    "    def __init__(self, name):\n",
    "        self.name = name\n",
    "        self.age = 19\n",
    "\n",
    "    def __call__(self, *args, **kwargs):\n",
    "        print(11111)\n",
    "\n",
    "\n",
    "obj = Foo(\"eric\")\n",
    "print(obj.name)\n",
    "print(obj.age)\n",
    "\n",
    "obj()  #默认对象()不可以执行"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'name': '张开', 'age': 19}\n"
     ]
    }
   ],
   "source": [
    "# `__dict__` 类的成员以字典的形式返回\n",
    "class Foo:\n",
    "    city = \"上海\"\n",
    "\n",
    "    def __init__(self, name):\n",
    "        self.name = name\n",
    "        self.age = 19\n",
    "\n",
    "\n",
    "obj = Foo(\"张开\")\n",
    "print(obj.__dict__)\n",
    "print(Foo.__dict__)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-18T06:52:25.822440Z",
     "start_time": "2024-01-18T06:52:25.756179Z"
    }
   },
   "execution_count": 15
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "张开-19\n"
     ]
    }
   ],
   "source": [
    "# `__str__`\n",
    "class Foo:\n",
    "    def __init__(self, name):\n",
    "        self.name = name\n",
    "        self.age = 19\n",
    "\n",
    "    # Java中toString\n",
    "    def __str__(self):\n",
    "        return \"{}-{}\".format(self.name, self.age)\n",
    "\n",
    "\n",
    "obj = Foo(\"张开\")\n",
    "print(obj)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-18T06:53:47.014213600Z",
     "start_time": "2024-01-18T06:53:46.923248900Z"
    }
   },
   "execution_count": 16
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "# __getitem__、 __setitem__、__delitem__ 类默认不支持用索引取值\n",
    "v1 = list([\"上海\", \"青海\", \"北京\"])\n",
    "\n",
    "print(v1[0])\n",
    "v1[1]\n",
    "v1[2]"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "class Foo:\n",
    "    def __init__(self, name):\n",
    "        self.name = name\n",
    "        self.age = 19\n",
    "\n",
    "    def __getitem__(self, item):\n",
    "        return 999\n",
    "\n",
    "    def __setitem__(self, key, value):\n",
    "        print(key, value)\n",
    "\n",
    "    def __delitem__(self, key):\n",
    "        print(key)\n",
    "\n",
    "\n",
    "obj = Foo(\"张开\")\n",
    "obj[0]\n",
    "obj[2] = \"哈哈哈哈\"\n",
    "del obj[777]"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "# `__enter__` `__exit__`\n",
    "with open(....) as f:\n",
    "    pass"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "class Foo:\n",
    "    def __init__(self, name):\n",
    "        self.name = name\n",
    "        self.age = 19\n",
    "\n",
    "    def __enter__(self):\n",
    "        print(\"进来了\")\n",
    "        return \"武沛齐\"\n",
    "\n",
    "    def __exit__(self, exc_type, exc_val, exc_tb):\n",
    "        print(\"出去了\")\n",
    "\n",
    "\n",
    "obj = Foo(\"张开\")\n",
    "\n",
    "with obj as f:\n",
    "    print(123)"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "# `__add__`  实现对象拼接\n",
    "class Foo:\n",
    "    def __init__(self, name):\n",
    "        self.name = name\n",
    "        self.age = 19\n",
    "\n",
    "    def __add__(self, other):\n",
    "        return self.age + other.age\n",
    "\n",
    "\n",
    "f1 = Foo(\"root\")\n",
    "f2 = Foo(\"admin\")\n",
    "\n",
    "data = f1 + f2  # f1.__add__(f2)\n",
    "print(data)"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 嵌套"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "class Student:\n",
    "    def __init__(self,name,age):\n",
    "        self.name = name\n",
    "        self.age = age\n",
    "        \n",
    "s1 = Student(\"武沛齐\",22) \n",
    "s2 = Student(\"张开\",12)\n",
    "s3 = Student(\"占山\",32)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-18T07:05:50.943372500Z",
     "start_time": "2024-01-18T07:05:50.897796200Z"
    }
   },
   "execution_count": 18
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "武沛齐\n",
      "张开\n"
     ]
    }
   ],
   "source": [
    "class Cls:\n",
    "    def __init__(self, title):\n",
    "        self.title = title\n",
    "        self.stu_list = []\n",
    "\n",
    "\n",
    "c1 = Cls(\"三年级\")\n",
    "c2 = Cls(\"五年级\")\n",
    "c1.stu_list.append(s1)\n",
    "c1.stu_list.append(s2)\n",
    "c2.stu_list.append(s3)\n",
    "\n",
    "print(c1.stu_list[0].name)\n",
    "print(c1.stu_list[1].name)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-18T07:05:53.199505700Z",
     "start_time": "2024-01-18T07:05:53.158673400Z"
    }
   },
   "execution_count": 19
  },
  {
   "cell_type": "markdown",
   "source": [],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 并发\n",
    "线程，IO密集型使用多线程：网络请求输入输出\n",
    "进程，计算（CPU）密集型使用多进程（Python内部的GIL锁：同一时刻同一个进程只有一个线程被使用）"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "![jupyter](./png/img_6.png)"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<Response [403]>\n",
      "<Response [403]>\n",
      "<Response [403]>\n",
      "<Response [403]>\n",
      "<Response [403]>\n",
      "<Response [403]>\n",
      "<Response [403]>\n",
      "<Response [403]>\n",
      "<Response [403]>\n",
      "<Response [403]>\n"
     ]
    }
   ],
   "source": [
    "import requests\n",
    "\n",
    "url_list = [\n",
    "    \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "    \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "    \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "    \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "    \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "    \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "    \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "    \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "    \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "    \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "]\n",
    "\n",
    "for url in url_list:\n",
    "    res = requests.get(url)\n",
    "    print(res)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-18T07:18:33.490918Z",
     "start_time": "2024-01-18T07:18:28.681182Z"
    }
   },
   "execution_count": 20
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 线程"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "import requests\n",
    "import threading\n",
    "\n",
    "\n",
    "def task(video_url):\n",
    "    res = requests.get(video_url)\n",
    "    print(res)\n",
    "\n",
    "\n",
    "url_list = [\n",
    "    \"https://www.zhihu.com/question/48312588/answer/3034670442\",\n",
    "    \"https://www.zhihu.com/question/48312588/answer/3034670442\",\n",
    "    \"https://www.zhihu.com/question/48312588/answer/3034670442\",\n",
    "    \"https://www.zhihu.com/question/48312588/answer/3034670442\",\n",
    "    \"https://www.zhihu.com/question/48312588/answer/3034670442\",\n",
    "    \"https://www.zhihu.com/question/48312588/answer/3034670442\",\n",
    "    \"https://www.zhihu.com/question/48312588/answer/3034670442\",\n",
    "    \"https://www.zhihu.com/question/48312588/answer/3034670442\",\n",
    "    \"https://www.zhihu.com/question/48312588/answer/3034670442\",\n",
    "    \"https://www.zhihu.com/question/48312588/answer/3034670442\",\n",
    "]\n",
    "\n",
    "for url in url_list:\n",
    "    t = threading.Thread(target=task, args=(url,))\n",
    "    t.start()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-18T07:44:31.066803700Z",
     "start_time": "2024-01-18T07:44:30.987064Z"
    }
   },
   "execution_count": 3
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 进程"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "import multiprocessing\n",
    "import requests\n",
    "\n",
    "\n",
    "def task(video_url):\n",
    "    res = requests.get(url=video_url)\n",
    "    print(res)\n",
    "\n",
    "\n",
    "def run():\n",
    "    url_list = [\n",
    "        \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "        \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "        \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "        \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "        \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "        \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "        \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "        \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "        \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "        \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "    ]\n",
    "    for url in url_list:\n",
    "        p = multiprocessing.Process(target=task, args=(url,))\n",
    "        p.start()\n",
    "\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    run()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-18T07:24:04.153878400Z",
     "start_time": "2024-01-18T07:24:03.775961100Z"
    }
   },
   "execution_count": 24
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 池\n",
    "防止无限制的开进程和线程"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 线程池"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "import time\n",
    "from concurrent.futures import ThreadPoolExecutor\n",
    "\n",
    "\n",
    "def task(video_url):\n",
    "    print(\"开始执行任务\")\n",
    "    time.sleep(4)\n",
    "\n",
    "\n",
    "pool = ThreadPoolExecutor(5)\n",
    "url_list = [\n",
    "    \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "    \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "    \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "    \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "    \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "    \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "    \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "    \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "    \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "    \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "    \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "    \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "    \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "    \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "    \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "    \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "    \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "    \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "    \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "    \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "]\n",
    "for url in url_list:\n",
    "    pool.submit(task, url)"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 进程池"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "import time\n",
    "from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor\n",
    "\n",
    "\n",
    "def task(video_url):\n",
    "    print(\"开始执行任务\")\n",
    "    time.sleep(4)\n",
    "\n",
    "\n",
    "def run():\n",
    "    pool = ProcessPoolExecutor(5)\n",
    "    url_list = [\n",
    "        \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "        \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "        \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "        \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "        \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "        \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "        \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "        \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "        \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "        \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "        \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "        \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "        \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "        \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "        \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "        \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "        \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "        \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "        \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "        \"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog\",\n",
    "    ]\n",
    "    for url in url_list:\n",
    "        pool.submit(task, url)\n",
    "\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    run()"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "markdown",
   "source": [],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 数据共享\n",
    "线程共享进程中的所有资源\n",
    "进程与进程之间，数据隔离"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "![jupyter](./png/img_7.png)"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1]\n",
      "[1, 2]\n",
      "[1, 2, 3]\n",
      "[1, 2, 3, 4]\n",
      "[1, 2, 3, 4, 5]\n"
     ]
    }
   ],
   "source": [
    "import time\n",
    "import threading\n",
    "\n",
    "data_list = []\n",
    "\n",
    "\n",
    "def task(index):\n",
    "    data_list.append(index)\n",
    "    print(data_list)\n",
    "\n",
    "\n",
    "def run():\n",
    "    for i in range(1, 6):\n",
    "        t = threading.Thread(target=task, args=(i,))\n",
    "        t.start()\n",
    "\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    run()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-18T07:41:00.847483600Z",
     "start_time": "2024-01-18T07:41:00.782908600Z"
    }
   },
   "execution_count": 1
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[]\n"
     ]
    }
   ],
   "source": [
    "import time\n",
    "import threading\n",
    "import multiprocessing\n",
    "\n",
    "\n",
    "def task(index, data_list):\n",
    "    data_list.append(index)\n",
    "    print(data_list)\n",
    "\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    data = []\n",
    "    for i in range(1, 6):\n",
    "        t = multiprocessing.Process(target=task, args=(i, data))\n",
    "        t.start()\n",
    "        t.join()\n",
    "    print(data)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-18T07:47:45.861840Z",
     "start_time": "2024-01-18T07:47:45.210009100Z"
    }
   },
   "execution_count": 4
  },
  {
   "cell_type": "markdown",
   "source": [
    "### Manager\n",
    "人为控制进程间数据共享，但生产中用第三方组件"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "import time\n",
    "import threading\n",
    "import multiprocessing\n",
    "from multiprocessing import Manager\n",
    "\n",
    "\n",
    "def task(data_list):\n",
    "    data_list.append(111)\n",
    "    data_list.append(333)\n",
    "    print(data_list)\n",
    "\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    manager = Manager()\n",
    "    with manager:\n",
    "        data = manager.list()\n",
    "        t = multiprocessing.Process(target=task, args=(data,))\n",
    "        t.start()\n",
    "        t.join()\n",
    "        print(data)"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 协程\n",
    "线程、进程是在计算机中真实存在的，协程本质不存在，是程序员人为创造出来。\n",
    "本质上就是让一个线程不要停，切换这做多个任务。\n",
    "开发过程中有IO等待，那么就适合用协程。"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "markdown",
   "source": [],
   "metadata": {
    "collapsed": false
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  },
  "widgets": {
   "application/vnd.jupyter.widget-state+json": {
    "state": {},
    "version_major": 2,
    "version_minor": 0
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
